package org.kl.wx.web;

import java.io.IOException;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;

import org.apache.commons.lang3.StringUtils;
import org.kl.bf.service.basic.UserService;
import org.kl.bf.web.base.BasicController;
import org.kl.wx.entity.App;
import org.kl.wx.service.EventRecordService;
import org.kl.wx.service.GroupsService;
import org.kl.wx.service.WxUserService;
import org.kl.wx.util.DemoEventHandler;
import org.kl.wx.util.DemoGuessNumberHandler;
import org.kl.wx.util.DemoImageHandler;
import org.kl.wx.util.DemoLogHandler;
import org.kl.wx.util.DemoOAuth2Handler;
import org.kl.wx.util.DemoTextHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 微信公众平台交互
 * 
 * @Author hqm
 * @CreateTime 2014-3-13 下午9:34:36
 */
@Controller
@RequestMapping(value = "/wx/mp")
public class WxMpController extends BasicController {

	@Autowired
	private EventRecordService eventRecordService;
	@Autowired
	private WxUserService wxUserService;
	@Autowired
	private GroupsService groupsService;
	@Autowired
	private UserService userService;

	@RequestMapping(value = "{token}")
	@ResponseBody
	public String list(@PathVariable("token") String token, ServletRequest request, HttpServletResponse response, HttpSession session)
			throws IOException {
		String signature = request.getParameter("signature");
		String nonce = request.getParameter("nonce");
		String timestamp = request.getParameter("timestamp");

		response.setContentType("text/html;charset=utf-8");
		response.setStatus(HttpServletResponse.SC_OK);
		WxMpService wxMpService = super.getWxMpServiceByToken(session, token);
		App wxApp = super.getWxAppByToken(session, token);
		if (wxMpService == null || !wxMpService.checkSignature(timestamp, nonce, signature)) {
			// 消息签名不正确，说明不是公众平台发过来的消息
			return "非法请求";
		}

		String echostr = request.getParameter("echostr");
		if (StringUtils.isNotBlank(echostr)) {
			// 说明是一个仅仅用来验证的请求，回显echostr
			return echostr;
		}

		String encryptType = StringUtils.isBlank(request.getParameter("encrypt_type")) ? "raw" : request.getParameter("encrypt_type");

		WxMpXmlMessage inMessage = null;

		if ("raw".equals(encryptType)) {
			// 明文传输的消息
			inMessage = WxMpXmlMessage.fromXml(request.getInputStream());
		} else if ("aes".equals(encryptType)) {
			// 是aes加密的消息
			String msgSignature = request.getParameter("msg_signature");
			inMessage = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), wxApp, timestamp, nonce, msgSignature);
		} else {
			return "不可识别的加密类型";
		}
		WxMpMessageRouter wxMpMessageRouter = new WxMpMessageRouter(wxMpService);
		WxMpMessageHandler logHandler = new DemoLogHandler();
		WxMpMessageHandler textHandler = new DemoTextHandler();
		WxMpMessageHandler imageHandler = new DemoImageHandler();
		WxMpMessageHandler oauth2handler = new DemoOAuth2Handler();
		DemoGuessNumberHandler guessNumberHandler = new DemoGuessNumberHandler();
		DemoEventHandler eventHandler = new DemoEventHandler(wxApp, eventRecordService, wxUserService, groupsService,userService);

		wxMpMessageRouter = new WxMpMessageRouter(wxMpService);
		wxMpMessageRouter.rule().handler(logHandler).next().rule().async(false).msgType(WxConsts.XML_MSG_EVENT).matcher(eventHandler)
				.handler(eventHandler).end().rule().msgType(WxConsts.XML_MSG_TEXT).matcher(guessNumberHandler).handler(guessNumberHandler)
				.end().rule().async(false).content("哈哈").handler(textHandler).end().rule().async(false).content("图片").handler(imageHandler)
				.end().rule().async(false).content("oauth").handler(oauth2handler).end();
		WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
		if (outMessage != null) {
			if ("raw".equals(encryptType)) {
				return outMessage.toXml();
			} else if ("aes".equals(encryptType)) {
				return outMessage.toEncryptedXml(wxApp);
			}
		}
		return null;
	}
}
